using System;
using System.Diagnostics;

namespace Magiq.Behaviors
{
    public abstract class BehaviorHandler<TBehavior> where TBehavior : IMagiqBehavior
    {
        protected void Default<TDefault>() where TDefault : TBehavior, new()
        {
            Default(new TDefault());
        }

        protected void Default<TDefault>(TDefault defaultBehavior) where TDefault : TBehavior
        {
            var behavior = BehaviorChain;

            while (behavior.NextBehavior != null)
                behavior = behavior.NextBehavior;

            behavior.NextBehavior = defaultBehavior;
        }

        protected IMagiqBehavior BehaviorChain { get; set; }

        protected BehaviorHandler(IMagiqBehavior behavior)
        {
            BehaviorChain = behavior;
        }
        
        [DebuggerStepThrough]
        protected void Call(Action<TBehavior> action)
        {
            MagiqBehavior.Execute(BehaviorChain, action);
        }

        [DebuggerStepThrough]
        protected TReturn Call<TReturn>(Func<TBehavior, TReturn> action)
        {
            return MagiqBehavior.Execute(BehaviorChain, action);
        }

        [DebuggerStepThrough]
        protected IMagiqBehaviorCaller<TOtherBehavior> Behavior<TOtherBehavior>() where TOtherBehavior : IMagiqBehavior
        {
            return new MagiqBehaviorCaller<TOtherBehavior>(BehaviorChain);
        }
    }
}